import { IMPORTANT, MEDIA_QUERIES, BASE_MEDIA_QUERY, PREFIX, PREFIX_SEPARATOR } from '../constant';
import { getConfig } from '../config';
import { groupBy, prefixStr, toRegexImportant } from './utils';

let preArray = [];
const queryObj = {};

export const pushPreObj = (obj: any) => {
    return preArray.push(obj as never);
}

export const getPreArray = () => {
    return preArray
}

export const clearPreArray = () => {
    preArray = []
}

export const pushQuery = (key: string | number, obj: any) => {
    // if queryObj has key then push else set key is Array
    if (Object.prototype.hasOwnProperty.call(queryObj, key)) {
        queryObj[key].push(obj)
    } else {
        queryObj[key] = [obj]
    }
}

const isImportant = () => getConfig(IMPORTANT);

const getCssSingle = ({ classStr, isPrefixStr, css, pseudo }) => {
    // console.log(classStr);
    // console.log(isPrefixStr);
    classStr = classStr.replace(/([@:#.])/g, '\\$1')
    if (pseudo) {
        classStr = classStr + `:${pseudo}`
    }
    let cssPrefix: string = prefixStr(isPrefixStr);
    let isImportantSingle = () => {
        if (!isImportant()) {
            return toRegexImportant(classStr);
        }

        return true;
    };

    return css.reduce((t: string, c: any) => t + (isImportantSingle() ? `${c} !important; ` : `${c}; `), `.${cssPrefix}${classStr}{ `) + '}'
}

const sortCss = (a: { num: any; } | undefined, b: { num: any; } | undefined) => {
    if (a !== undefined && b !== undefined) {
        return Number(a.num) - Number(b.num)
    } else {
        return 0
    }
}

const renderArray = (array: any[]) => {
    let cssStr = ''
    const cssObject = groupBy(array.sort((a: { order: number; }, b: { order: number; }) => a.order - b.order), 'name')
    // console.log(array);
    for (const key in cssObject) {
        if (Object.prototype.hasOwnProperty.call(cssObject, key)) {
            // cssStr += `/* ${cssObject[key][0].name || 'unknow name'} order ${cssObject[key][0].order} */\n`
            cssStr += `/* ${cssObject[key][0].name || 'unknow name'} */\n`;
            cssStr += cssObject[key]
                .sort(sortCss)
                .map(getCssSingle)
                .join('\n')
            cssStr += '\n'
        }
    }
    return cssStr
}

export const renderCss = () => {
    let cssStr = ''
	// console.log(preArray);
    cssStr += renderArray(preArray)
    // console.log(cssStr)
    const queryConfigObj = { ...BASE_MEDIA_QUERY, ...getConfig(MEDIA_QUERIES) }
    for (const key in queryObj) {
        if (Object.prototype.hasOwnProperty.call(queryObj, key)) {
            cssStr += `@media ${queryConfigObj[key]}{\n`
            cssStr += renderArray(queryObj[key])
            cssStr += '}'
        }
    }
    return cssStr
}